import { computed, ref, watchEffect, type Ref } from 'vue'
import { plot, ruleY, axisY, axisX, line, crosshair, text } from '@observablehq/plot'

export function useLineChart(points: Ref<[number[], number[]]>) {
  const figureRef = ref<HTMLElement | null>(null)
  const data = computed<[x: number, y: number][]>(() =>
    points.value[0].map((x, i) => [x, points.value[1][i]])
  )

  const staticPlot = [
    text(['信噪比与正确率关系仿真结果'], {
      frameAnchor: 'top',
      dy: -24,
      fontSize: '16px',
      fontWeight: 'bold'
    }),
    ruleY([1], { opacity: 0 }),
    axisY({
      fontSize: '14px',
      label: '正确率',
      anchor: 'left',
      labelAnchor: 'center'
    }),
    axisX({
      fontSize: '14px',
      label: '信噪比',
      anchor: 'bottom',
      labelAnchor: 'center'
    })
  ]
  watchEffect(() => {
    if (figureRef.value === null) return

    const Chart = plot({
      y: { type: 'linear', grid: true },
      x: { type: 'log', grid: true },
      marks: [
        ...staticPlot,
        line(data.value.slice(10), {
          marginTop: 28,
          marginLeft: 60,
          marginBottom: 40,
          x: ([x]) => x,
          y: ([, y]) => y,
          stroke: '#80AE8A',
          marker: 'tick'
        }),
        crosshair(data.value.slice(10), {
          x: ([x]) => x,
          y: ([, y]) => y,
          color: 'red',
          opacity: 0.4
        })
      ]
    })

    if (figureRef.value.firstChild !== null) {
      figureRef.value.firstChild.replaceWith(Chart)
    } else {
      figureRef.value.appendChild(Chart)
    }
  })

  return {
    figureRef
  }
}
